package main

import (
	"fmt"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"image"
	"image/draw"
	"log"
	"os"
	"sort"
)

// ┌───────┬─────────────────┬───────┐
// │   1   │        4        │   7   │
// ├───────┼─────────────────┼───────┤
// │       │                 │       │
// │   2   │        5        │   8   │
// │       │                 │       │
// ├───────┼─────────────────┼───────┤
// │   3   │        6        │   9   │
// └───────┴─────────────────┴───────┘
// ┌───────┬─────────────────┬──────┬─────────────────────────┬──────┐
// │   1   │        4        │   7  │           10            │   13 │
// ├───────┼─────────────────┼──────┼─────────────────────────┼──────┤
// │       │                 │      │                         │      │
// │   2   │        5        │   8  │           11            │   14 │
// │       │                 │      │                         │      │
// ├───────┼─────────────────┼──────┼─────────────────────────┼──────┤
// │   3   │        6        │   9  │           12            │   15 │
// └───────┴─────────────────┴──────┴─────────────────────────┴──────┘
func splitImage(img image.Image, point ...*image.Point) (error, map[int]image.Image) {
	if len(point) < 2 || len(point)%2 != 0 {
		return fmt.Errorf("图片生成失败, 输入点非法"), nil
	}
	var mapWidthStep = map[int]int{}
	var mapHeightStep = map[int]int{}
	var prev *image.Point
	for i := 0; i < len(point); i++ {
		p := point[i]
		if i < 2 {
			if prev != nil {
				if prev.X > p.X || prev.Y > p.Y {
					return fmt.Errorf("图片生成失败, 输入点非法"), nil
				}
			}
			mapWidthStep[i] = p.X
			mapHeightStep[i] = p.Y
			prev = p
			continue
		} else {
			if prev.Y > p.Y {
				return fmt.Errorf("图片生成失败, 输入点非法"), nil
			}
		}
		mapWidthStep[i] = p.X
		prev = p
	}
	if len(mapWidthStep) == 0 || len(mapHeightStep) == 0 {
		return fmt.Errorf("图片生成失败, 输入点非法"), nil
	}
	// 获取图片的尺寸
	width := img.Bounds().Dx()
	height := img.Bounds().Dy()
	if mapWidthStep[len(mapWidthStep)-1] >= width || mapWidthStep[len(mapWidthStep)-1] >= width {
		return fmt.Errorf("图片生成失败, 输入点非法"), nil
	}
	mapWidthStep[len(mapWidthStep)] = int(width)
	mapHeightStep[len(mapHeightStep)] = int(height)

	calcRectMap := map[int]*image.Rectangle{}
	for i := 0; i < len(mapWidthStep); i++ {
		for j := 0; j < len(mapHeightStep); j++ {
			index := i*3 + j + 1
			var startPointY int
			if j == 0 {
				startPointY = 0
			} else {
				startPointY = mapHeightStep[j-1]
			}
			var startPointX int
			if i == 0 {
				startPointX = 0
			} else {
				startPointX = mapWidthStep[i-1]
			}
			o := &image.Rectangle{
				Min: image.Point{startPointX, startPointY},
				Max: image.Point{mapWidthStep[i], mapHeightStep[j]},
			}
			calcRectMap[index] = o
		}
	}

	pointList := []*image.Point{}

	pointList = append(pointList, point...)
	pointList = append(pointList, &image.Point{width, height})
	//排序pointList
	sort.Slice(pointList, func(i, j int) bool {
		return pointList[i].X < pointList[j].X
	})

	genCount := (len(point) + 1) * 3
	_ = genCount
	// 生成切分格子
	imgMap := map[int]image.Image{}
	for i := 1; i <= len(calcRectMap); i++ {
		imgMap[i] = segmentPic(&img, calcRectMap[i])
		log.Printf("--------------------&v\n", calcRectMap[i])
	}
	return nil, imgMap
}

// 该函数用于将图像分割成指定矩形区域
func segmentPic(img *image.Image, rc *image.Rectangle) *image.RGBA {
	// 创建一个新的RGBA图像，大小为指定矩形区域的大小
	newImg := image.NewRGBA(image.Rect(0, 0, rc.Dx(), rc.Dy()))
	// 将原图像中指定矩形区域的内容绘制到新图像中
	draw.Draw(newImg, newImg.Bounds(), *img, image.Point{rc.Min.X, rc.Min.Y}, draw.Src)
	// 返回新图像
	return newImg
}
func mergeImages(imgMap map[int]image.Image) image.Image {
	if len(imgMap) == 0 {
		return nil
	}
	// 计算合并后图像的宽度和高度
	var mapWidthStep = map[int]int{}
	var mapHeightStep = map[int]int{}
	for i := 1; i <= len(imgMap); i++ {
		img, ok := imgMap[i]
		if !ok {
			continue
		}
		indexX := (i - 1) / 3
		tWidth := img.Bounds().Dx()
		lastWidth := mapWidthStep[indexX]
		if lastWidth < tWidth {
			mapWidthStep[indexX] = tWidth
		}

		indexY := (i - 1) % 3
		tHeight := img.Bounds().Dy()
		lastHeight := mapHeightStep[indexY]
		if lastHeight < tHeight {
			mapHeightStep[indexY] = tHeight
		}
	}

	var mapWidthIndex = map[int]int{}
	var mapHeightIndex = map[int]int{}
	totalWidth := 0
	totalHeight := 0
	for i := 0; i < len(mapWidthStep); i++ {
		mapWidthIndex[i] = totalWidth
		totalWidth += mapWidthStep[i]
		mapWidthIndex[i+1] = totalWidth
	}
	for i := 0; i < len(mapHeightStep); i++ {
		mapHeightIndex[i] = totalHeight
		totalHeight += mapHeightStep[i]
		mapHeightIndex[i+1] = totalHeight
	}
	// 创建一个新的图像
	mergedImage := image.NewRGBA(image.Rect(0, 0, totalWidth, totalHeight))

	// 将每个图像绘制到新图像上
	xOffset := 0
	yOffset := 0
	for i := 1; i <= len(imgMap); i++ {
		img := imgMap[i]
		if img == nil {
			continue
		}
		indexX := (i - 1) / 3
		indexY := (i - 1) % 3
		xOffset = mapWidthIndex[indexX]
		yOffset = mapHeightIndex[indexY]
		draw.Draw(mergedImage, image.Rect(xOffset, yOffset, xOffset+img.Bounds().Dx(), yOffset+img.Bounds().Dy()), img, image.Point{0, 0}, draw.Over)

	}

	return mergedImage
}

func main() {
	a := app.New()
	w := a.NewWindow("Image Splitter")

	// 打开图片文件
	file, err := os.Open("gui/other/przesun-o-10-krokow.png") // 替换为您的图片路径
	if err != nil {
		panic(err)
	}
	defer file.Close()

	// 解码图片
	img, _, err := image.Decode(file)
	if err != nil {
		panic(err)
	}
	//46 23 5 5
	err, imgMap := splitImage(img,
		&image.Point{72, 10},
		&image.Point{73, 12},
		&image.Point{92, 12},
		&image.Point{93, 12},
	)
	if err != nil {
		return
	}
	/*

		 // 创建两个新的图像
			leftImg := image.NewRGBA(image.Rect(0, 0, width/2, height))
			rightImg := image.NewRGBA(image.Rect(0, 0, width/2, height))

			// 将原始图像的一半绘制到新的图像上
			draw.Draw(leftImg, leftImg.Bounds(), img, image.Point{0, 0}, draw.Src)
			draw.Draw(rightImg, rightImg.Bounds(), img, image.Point{width / 2, 0}, draw.Src)


				// 切分图片
				leftImg, rightImg := splitImage(img)

				// 创建图像组件
				baseImage := canvas.NewImageFromImage(leftImg)
				rightImage := canvas.NewImageFromImage(rightImg)

				// 设置图像的最小尺寸
				baseImage.SetMinSize(fyne.NewSize(float32(leftImg.Bounds().Dx()), float32(leftImg.Bounds().Dy())))
				rightImage.SetMinSize(fyne.NewSize(float32(rightImg.Bounds().Dx()), float32(rightImg.Bounds().Dy())))*/
	// 创建布局
	baseImage := canvas.NewImageFromImage(img)
	baseImage.SetMinSize(fyne.NewSize(float32(img.Bounds().Dx()), float32(img.Bounds().Dy())))
	content := container.NewHBox(baseImage)

	fn := func(a, b *image.Point) {
		pic1 := segmentPic(&img, &image.Rectangle{*a, *b})
		pic1Image := canvas.NewImageFromImage(pic1)
		pic1Image.SetMinSize(fyne.NewSize(float32(pic1.Bounds().Dx()), float32(pic1.Bounds().Dy())))
		content.Add(pic1Image)
	}
	fn2 := func(a, b *image.Point) {
		pic1 := segmentPic(&img, &image.Rectangle{*a, *b})

		mergedImage := image.NewRGBA(image.Rect(0, 0, pic1.Bounds().Dx()*2, pic1.Bounds().Dy()*2))
		stretchDraw(mergedImage, image.Rect(0, 0, pic1.Rect.Dx(), pic1.Rect.Dy()), pic1)

		pic1Image := canvas.NewImageFromImage(mergedImage)
		pic1Image.SetMinSize(fyne.NewSize(float32(mergedImage.Bounds().Dx()), float32(mergedImage.Bounds().Dy())))
		content.Add(pic1Image)
	}
	_ = fn
	_ = fn2
	//fn(&image.Point{0, 0}, &image.Point{35, 10})
	//fn2(&image.Point{0, 0}, &image.Point{35, 10})
	//fn(&image.Point{0, 10}, &image.Point{35, 50})
	//fn2(&image.Point{0, 10}, &image.Point{35, 50})
	//fn(&image.Point{0, 50}, &image.Point{35, 64})
	//fn2(&image.Point{0, 50}, &image.Point{35, 64})

	//for i := 0; i < len(imgMap); i++ {
	//	pImg := imgMap[i+1]
	//	splitImage := canvas.NewImageFromImage(pImg)
	//	splitImage.SetMinSize(fyne.NewSize(float32(pImg.Bounds().Dx()), float32(pImg.Bounds().Dy())))
	//	content.Add(splitImage)
	//}
	//bagImg := mergeImages(imgMap)
	bagImg := mergeImages9sprite(imgMap,
		fyne.NewSize(float32(img.Bounds().Dx()+1), float32(1)),
		fyne.NewSize(float32(img.Bounds().Dx()+1), float32(1)),
	)

	bImage := canvas.NewImageFromImage(bagImg)
	bImage.SetMinSize(fyne.NewSize(float32(bagImg.Bounds().Dx()), float32(bagImg.Bounds().Dy())))
	content.Add(bImage)
	w.SetContent(content)
	w.Resize(fyne.NewSize(800, 400))
	w.ShowAndRun()
}

func mergeImages9sprite(imgMap map[int]image.Image, addSize ...fyne.Size) image.Image {
	if len(imgMap) == 0 || addSize == nil {
		return nil
	}
	// 计算合并后图像的宽度和高度
	var mapWidthStep = map[int]int{}
	var mapHeightStep = map[int]int{}
	for i := 1; i <= len(imgMap); i++ {
		img, ok := imgMap[i]
		if !ok {
			continue
		}
		indexX := (i - 1) / 3
		tWidth := img.Bounds().Dx()
		lastWidth := mapWidthStep[indexX]
		if lastWidth < tWidth {
			mapWidthStep[indexX] = tWidth
		}

		indexY := (i - 1) % 3
		tHeight := img.Bounds().Dy()
		lastHeight := mapHeightStep[indexY]
		if lastHeight < tHeight {
			mapHeightStep[indexY] = tHeight
		}
	}

	var mapWidthIndex = map[int]int{}
	var mapHeightIndex = map[int]int{}
	totalWidth := 0
	totalHeight := 0
	for i := 0; i < len(mapWidthStep); i++ {
		mapWidthIndex[i] = totalWidth
		totalWidth += mapWidthStep[i]
		if i%2 == 1 {
			order := (i - 1) / 2
			// 纵向拉伸
			totalWidth += int(addSize[order].Width)
		}
		mapWidthIndex[i+1] = totalWidth
	}
	for i := 0; i < len(mapHeightStep); i++ {
		mapHeightIndex[i] = totalHeight
		totalHeight += mapHeightStep[i]
		if i%2 == 1 {
			totalHeight += int(addSize[0].Height)
		}
		mapHeightIndex[i+1] = totalHeight
	}
	//  计算合并后图像的宽度和高度，高度只计算一次，宽度计算多次·
	//for i := 0; i < len(addSize); i++ {
	//	totalWidth += int(addSize[i].Width)
	//	if i == 0 {
	//		totalHeight += int(addSize[i].Height)
	//	}
	//}
	// 创建一个新的图像
	mergedImage := image.NewRGBA(image.Rect(0, 0, totalWidth, totalHeight))

	// 将每个图像绘制到新图像上
	xOffset := 0
	yOffset := 0

	//  ┌───0───┬────────1────────┬───2──┬──────────3──────────────┬───4──┐
	//0 │   1   │        4        │   7  │           10            │   13 │
	//  ├───────┼─────────────────┼──────┼─────────────────────────┼──────┤
	//  │       │                 │      │                         │      │
	//1 │   2   │        5        │   8  │           11            │   14 │
	//  │       │                 │      │                         │      │
	//  ├───────┼─────────────────┼──────┼─────────────────────────┼──────┤
	//2 │   3   │        6        │   9  │           12            │   15 │
	//  └───────┴─────────────────┴──────┴─────────────────────────┴──────┘
	for i := 1; i <= len(imgMap); i++ {
		img := imgMap[i]
		if img == nil {
			continue
		}
		indexX := (i - 1) / 3
		indexY := (i - 1) % 3
		xOffset = mapWidthIndex[indexX]
		yOffset = mapHeightIndex[indexY]
		xOffsetNext := mapWidthIndex[indexX+1]
		yOffsetNext := mapHeightIndex[indexY+1]
		//newHeight := 0
		//newWidth := 0
		//if indexY == 1 {
		//	// 纵向拉伸
		//	newHeight = int(addSize[0].Width)
		//}
		//if indexX%2 == 1 {
		//	addIndex := indexX / 2
		//	newHeight = int(addSize[addIndex].Width)
		//}
		stretchDraw(mergedImage,
			image.Rect(
				xOffset,
				yOffset,
				xOffsetNext, //+newWidth,
				yOffsetNext, //+newHeight
			),
			img)
		//if i == 2 {
		//	break
		//}
		//draw.Draw(mergedImage, image.Rect(xOffset, yOffset, xOffset+img.Bounds().Dx(), yOffset+img.Bounds().Dy()), img, image.Point{0, 0}, draw.Over)
	}
	return mergedImage
}

// stretchDraw 绘制时拉伸源图像到目标区域
func stretchDraw(dst *image.RGBA, dstRect image.Rectangle, src image.Image) {
	// 创建一个新的图像用于拉伸
	stretched := image.NewRGBA(image.Rectangle{
		Min: image.Point{0, 0},
		Max: image.Point{dstRect.Dx(), dstRect.Dy()},
	})

	// 按比例进行缩放
	for y := 0; y < dstRect.Dy(); y++ {
		for x := 0; x < dstRect.Dx(); x++ {
			srcX := x * src.Bounds().Dx() / dstRect.Dx()
			srcY := y * src.Bounds().Dy() / dstRect.Dy()
			stretched.Set(x, y, src.At(srcX, srcY))
		}
	}

	// 将拉伸图像绘制到目标图像上
	draw.Draw(dst, dstRect, stretched, image.Point{0, 0}, draw.Over)
}
